/*************************************************************************************************************
*                                                    UTOS
*                               A non-preemptive(cooperative) multitasking RTOS Kernel
*
* Copyright (c) 2013, HuangLiang (huangliang.tj@gmail.com)
* Under New BSD license, see "LICENSE" for detail
*
* @.file       utos_event.c
* @.version    refer to macro "UT_VERSION" in utos.h
* @.brief      
* 
*************************************************************************************************************/
#include "utos.h"

void    UT_Evt_Init(void)
{
    UT_INT32U i;
    UT_MemClr(&UT_EVENT_Pool[0], sizeof(UT_EVENT_Pool));
    
    for(i=0;i<UT_EVENT_MAX-1;i++)
    {
        UT_EVENT_Pool[i].ptr = (UT_EVENT*)&UT_EVENT_Pool[i+1];
        UT_EVENT_Pool[i].event_type = UT_EVT_TYPE_INIT;
        UT_EVENT_Pool[i].event_opt  = UT_EVT_OPT_COST;
    }
    UT_EVENT_Pool[i].ptr        = (void*)0;             // Last node's next is Null
    UT_EVENT_Pool[i].event_type = UT_EVT_TYPE_INIT;     // for last one
    UT_EVENT_Pool[i].event_opt  = UT_EVT_OPT_COST;
    UT_EVENT_Free_Entry         = &UT_EVENT_Pool[0];
    UT_EVENT_Created_Num        = 0;
}
UT_EVENT *  UT_Evt_Create(UT_TCB *p_thrd)
{
    UT_EVENT * rtn;
    
    if(UT_EVENT_Free_Entry&&p_thrd)
    {
        rtn                     = UT_EVENT_Free_Entry;
        UT_EVENT_Free_Entry     = (UT_EVENT *)UT_EVENT_Free_Entry->ptr;  //next evt
        rtn->ptr                = (void*)0;
        rtn->p_thread           = p_thrd;

        p_thrd->p_event         = rtn;
        UT_EVENT_Created_Num++;
        UT_Evt_Active(rtn);       //Set event active as default
        return rtn;
    }
    else
        return (UT_EVENT*)0;
}
UT_INT8U  UT_Evt_Delete(UT_EVENT *p_event)
{
    if(p_event)
    {
        UT_Evt_Mute(p_event);
        p_event->p_thread->p_event = (UT_EVENT*)0;
        
        
        p_event->event_type        = UT_EVT_TYPE_INIT;
        p_event->event_opt         = UT_EVT_OPT_COST;
        

        p_event->ptr               = UT_EVENT_Free_Entry;
        UT_EVENT_Free_Entry        = p_event;
        UT_EVENT_Created_Num--;
        return UT_ERR_NONE;
    }
    else
        return UT_ERR_PNULL;
        
}
UT_INT8U    UT_Evt_Mute(UT_EVENT *p_event)
{
    if(!p_event->p_thread)
        return UT_ERR_EVT_NOT_CREATE;
    p_event->p_thread->stat &= ~UT_TCB_STAT_EVT_PEND;
    return UT_ERR_NONE;
}
UT_INT8U    UT_Evt_Active(UT_EVENT *p_event)
{
    if(!p_event->p_thread)
        return UT_ERR_EVT_NOT_CREATE;
    p_event->p_thread->stat |= UT_TCB_STAT_EVT_PEND;
    return UT_ERR_NONE;
}
// Must makesure p_event is not NULL
UT_INT8U    UT_Evt_Signal(UT_EVENT *p_event)
{
    if(p_event->p_thread->p_pcb->stat & UT_PCB_STAT_MUTE)
        return UT_ERR_PROC_MUTED;
    if(p_event->p_thread->stat & UT_TCB_STAT_SLEEP)
        return UT_ERR_THRD_ASLEEP;
    if((p_event->p_thread->stat & UT_TCB_STAT_EVT_PEND) == 0)
        return UT_ERR_EVT_MUTED;
    
    return  UT_Core_Set_HighRdy(p_event->p_thread->p_pcb, p_event->p_thread);

}
UT_INT8U   UT_Evt_Set_Opt(UT_EVENT * p_event, UT_INT8U evt_opt)
{
    if(!p_event)
        return UT_ERR_PNULL;
    p_event->event_opt = evt_opt;
    return UT_ERR_NONE;
}
/*************************************************************************************************************
*                                                  END
*************************************************************************************************************/
